// as：给引入的包取别名，当多个包中包含相同名字的属性或方法时，这个关键字很有必要
import 'package:http/http.dart' as http;

/**
 * dart有两个队列，一个是微任务队列microtask queue，另一个是事件队列event queue
 * 
 * 微任务队列的优先级比较高，等到微任务队列的事件执行完就去执行事件队列，事件队列执行完就会退出程序。微任务队列的目的就是在当前事件处理完之后下个事件开始之前可以执行一些其他事务。
 * 但是，在任务执行的过程中也可以插入新的微任务和事件任务，就会一直循环执行下去，不会退出。
 * 
 * event queue: 包含了所有的外部事件：I/O，鼠标点击，绘制，定时器，Dart isolate 中的消息等等。自于 Dart 和系统的事件
 * microtask queue：事件处理代码有时需要在当前 event 之后，且在下一个 event 之前做一些任务。仅仅包含了来自于 Dart 内部的事件。
 * 
 * 参考资料：
 * 1. https://blog.csdn.net/ZZB_Bin/article/details/121497012
 * 2. https://www.jianshu.com/p/f0d9d983efff
 */
main() {
  _startMethod();
  print("C开始");
  /*
    如果加了下面这行代码，打印出"A开始执行这个方法~"和"C开始"后，程序会等待10秒才打印剩下的内容，即使http已经拿到了返回结果
    这是因为dart所谓的异步其实只是发送事件到EventLoop中排队等候处理，这个队列是单线程执行的，所以必须等待sleep结束才会取出后面的事件执行
  */
  // sleep(Duration(seconds: 10));
}

/**
 * async表示它是异步的方法
 */
Future _startMethod() async {
  print("A开始执行这个方法~");
  /*
    await的作用是等待标记的方法的返回结果，必须在async的方法内使用
    如果没有加await，getHttp()会立刻返回一个future，不等待方法内的代码执行完，就继续执行下面的方法，这里打印出来的结果也会变成——Instance of 'Future<String>'
  */
  print(await getHttp());
  print("A执行结束");
}

Future<String> getHttp() async {
  var uri = new Uri.http('news-at.zhihu.com', '/api/3/stories/latest');
  // 等待响应
  var response = await http.get(uri);
  // 返回响应的内容
  return await response.body.toString();
}
